package net.zjitc.service.impl;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import net.zjitc.common.Const;
import net.zjitc.common.ServiceResponse;
import net.zjitc.common.TockenCache;
import net.zjitc.mapper.UserMapper;
import net.zjitc.pojo.User;
import net.zjitc.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.UUID;

/**
 * @author 赵静静
 * @date 2019/3/22 12:09
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public ServiceResponse<User> login(String username, String password) {

        /*1.先检查用户名是否存在
        * 2.如果用户名存在再登录
        * */

        int resultCount = userMapper.checkUsername(username);
        if (resultCount==0){
            return ServiceResponse.createByErrorMessage("用户名不存在");
        }

        //todo md5加密
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        User user = userMapper.selectLogin(username,password);
        if (user == null){
            return ServiceResponse.createByErrorMessage("密码错误");
        }

        /*登录成功，密码置空后，返回user对象*/
       user.setPassword(StringUtils.EMPTY);
       return ServiceResponse.createBySuccess("登录成功",user);
    }


    @Override
    public ServiceResponse<String> register(User user) {
      /*  int resultCount = userMapper.checkUsername(user.getUsername());
        if (resultCount>0){
            return ServiceResponse.createByErrorMessage("用户名已经被注册");
        }*/
        //代码的复用性
        ServiceResponse<String> validResponse = this.checkValid(user.getUsername(), Const.USERNAME);
        if (!validResponse.isSuccess()){
            return validResponse;
        }
        validResponse = this.checkValid(user.getEmail(),Const.EMAIL);
        if (!validResponse.isSuccess()){
            return validResponse;
        }

        //设置用户角色
        user.setRole(Const.Role.ROLE_CUSTOMER);
        //对密码进行MD5加密
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        //注册
        int resultCount =  userMapper.insert(user);
        if (resultCount == 0){
            return ServiceResponse.createByErrorMessage("注册失败");
        }
        return ServiceResponse.createBySuccessMessage("注册成功");
    }

    /**
     * 检验数据类型的有效性
     * @param str
     * @param type
     * @return
     */
    @Override
    public ServiceResponse<String> checkValid(String str, String type) {
        //类型不为空的时候才校验
        if (StringUtils.isNoneBlank(type)){
            if (Const.USERNAME.equals(type)){
                int resultCount = userMapper.checkUsername(str);
                if (resultCount>0){
                    return ServiceResponse.createByErrorMessage("用户名已经被注册");
                }
            }
            if (Const.EMAIL.equals(type)){
                int resultCount = userMapper.checkEmail(str);
                if (resultCount>0){
                    return ServiceResponse.createByErrorMessage("Email已经被使用");
                }
            }

        }
        return ServiceResponse.createBySuccessMessage("校验通过");
    }

    @Override
    public ServiceResponse<String> selectQuestion(String username) {
        //检查用户名是否已经存在
        ServiceResponse<String> validResponse = this.checkValid(username, Const.USERNAME);
        if (validResponse.isSuccess()){ //用户名有效，则表示用户名不存在
            return ServiceResponse.createByErrorMessage("用户名不存在");
        }
        String question = userMapper.selectQuestionByUsername(username);
        if (StringUtils.isNotBlank(question)){
            return ServiceResponse.createBySuccess(question);
        }
        return ServiceResponse.createByErrorMessage("找回密码的问题是空的");
    }

    @Override
    public ServiceResponse<String> checkAnswer(String username, String question, String answer) {
        //先保证问题及答案正确
        int resultCount = userMapper.checkAnswer(username,question,answer);
        if (resultCount>0){
            //
            String forgetTocken = UUID.randomUUID().toString();
            TockenCache.setKey(TockenCache.TOCKEN_PREFIX+username,forgetTocken);
            return ServiceResponse.createBySuccess(forgetTocken);
        }
        return ServiceResponse.createByErrorMessage("问题的答案错误");
    }

    @Override
    public ServiceResponse<String> forgetRestPassword(String username, String newPassword, String forgetToken) {
        //验证tocken是否为空
        if (StringUtils.isBlank(forgetToken)){
            return ServiceResponse.createByErrorMessage("参数错误，tocken需要传值");
        }
        //验证用户名是否有效
        ServiceResponse<String> validResponse = this.checkValid(username, Const.USERNAME);
        if (validResponse.isSuccess()){
            return ServiceResponse.createByErrorMessage("用户名不存在");
        }

        //验证缓存中的tocken值
        String tocken = TockenCache.getKey(TockenCache.TOCKEN_PREFIX+username);
        if (StringUtils.isBlank(tocken)){
            return ServiceResponse.createByErrorMessage("tocken无效或者过期");
        }

        //比较传的forget与缓存中的tocken是否一致,并更新密码
        if (StringUtils.equals(tocken,forgetToken)){
            String md5Password = DigestUtils.md5DigestAsHex(newPassword.getBytes());
            int resultCount = userMapper.updatePasswordByUsername(username,md5Password);
            if (resultCount>0){
                return ServiceResponse.createBySuccessMessage("修改密码成功");
            }
        }else {
            return ServiceResponse.createByErrorMessage("tocken错误，请重新获取重置密码的tocken");
        }
        return ServiceResponse.createByErrorMessage("重置密码失败");
    }

    @Override
    public ServiceResponse<String> resetPassword(String oldPassword, String newPassword, User user) {
       //防止横向越权，要对旧密码进行验证(注意密码加密过)

        int resultCount = userMapper.checkPassword(DigestUtils.md5DigestAsHex(oldPassword.getBytes()),user.getId());
        if (resultCount==0){
            return ServiceResponse.createByErrorMessage("旧密码错误");
        }
        //更新密码
        user.setPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
       resultCount = userMapper.updateByPrimaryKeySelective(user);
       if (resultCount>0){
           user.setPassword(StringUtils.EMPTY);
           return ServiceResponse.createBySuccessMessage("修改密码成功");
       }
        return ServiceResponse.createByErrorMessage("修改密码失败");
    }

}
